<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Nametag Example — Networked-Aframe</title>
    <meta name="description" content="Nametag — Networked-Aframe" />

    <script src="https://aframe.io/releases/1.7.0/aframe.min.js"></script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.8.1/socket.io.min.js"></script>
    <script src="/easyrtc/easyrtc.js"></script>
    <script src="/dist/networked-aframe.js"></script>

    <script src="https://cdn.jsdelivr.net/gh/c-frame/aframe-extras@7.5.4/dist/aframe-extras.controls.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/aframe-environment-component@1.5.0/dist/aframe-environment-component.min.js"></script>
    <script src="/js/spawn-in-circle.component.js"></script>

    <script>
      // Temporary workaround for template declaration; see issue 167
      NAF.schemas.getComponentsOriginal = NAF.schemas.getComponents;
      NAF.schemas.getComponents = (template) => {
        if (!NAF.schemas.hasTemplate('#head-template')) {
          NAF.schemas.add({
            template: '#head-template',
            components: [
              {
                component: 'position',
                requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.001)
              },
              {
                component: 'rotation',
                requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.5)
              },

              // In this example, we don't sync the material.color itself, like the basic example;
              // we instead sync player-info, which includes color setting + updating.
              // (you can see an example of the other pattern in the basic.html demo)
              'player-info'
            ]
          });
        }

        if (!NAF.schemas.hasTemplate('#rig-template')) {
          NAF.schemas.add({
            template: '#rig-template',
            components: [
              {
                component: 'position',
                requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.001)
              },
              {
                component: 'rotation',
                requiresNetworkUpdate: NAF.utils.vectorRequiresUpdate(0.5)
              }
            ]
          });
        }

        const components = NAF.schemas.getComponentsOriginal(template);
        return components;
      };
    </script>

    <script>
      window.ntExample = {
        randomColor: () => {
          return '#' + new THREE.Color(Math.random(), Math.random(), Math.random()).getHexString();
        }
      };

      AFRAME.registerComponent('player-info', {
        // notice that color and name are both listed in the schema; NAF will only keep
        // properties declared in the schema in sync.
        schema: {
          name: { type: 'string', default: 'user-' + Math.round(Math.random() * 10000) },
          color: {
            type: 'color', // btw: color is just a string under the hood in A-Frame
            default: window.ntExample.randomColor()
          }
        },

        init: function () {
          this.head = this.el.querySelector('.head');
          this.nametag = this.el.querySelector('.nametag');

          this.ownedByLocalUser = this.el.id === 'player';
          if (this.ownedByLocalUser) {
            // populate the html overlay with the correct name on init
            this.nametagInput = document.getElementById('username-overlay');
            this.nametagInput.value = this.data.name;

            // add the initial color to the html overlay color picker button
            document.querySelector('#color-changer').style.backgroundColor = this.data.color;
            document.querySelector('#color-changer').style.color = this.data.color;
          }
        },

        // here as an example, not used in current demo. Could build a user list, expanding on this.
        listUsers: function () {
          console.log(
            'userlist',
            [...document.querySelectorAll('[player-info]')].map((el) => el.components['player-info'].data.name)
          );
        },

        newRandomColor: function () {
          this.el.setAttribute('player-info', 'color', window.ntExample.randomColor());
        },

        update: function () {
          if (this.head) this.head.setAttribute('material', 'color', this.data.color);
          if (this.nametag) this.nametag.setAttribute('value', this.data.name);
        }
      });
    </script>
  </head>

  <body>
    <!-- This <button> and <input> will overlay on top of the A-Frame canvas--this style is all you need.
         Note the onclick and oninput attributes; on every call, they will run .setAttribute() for the player-info
         component's data. NAF will keep that property in sync, since 'name' and 'color' are declared in the schema
         of the 'player-info' component
    -->
    <button
      id="color-changer"
      style="z-index: 100; bottom: 24px; left: 24px; position: fixed"
      onclick="let newColor = window.ntExample.randomColor();
             document.getElementById('player').setAttribute('player-info', 'color', newColor); 
             document.querySelector('#color-changer').style.backgroundColor = newColor;
             document.querySelector('#color-changer').style.color = newColor;
    "
    >
      ■
    </button>
    <input
      id="username-overlay"
      style="z-index: 100; bottom: 24px; left: 48px; position: fixed"
      oninput="document.getElementById('player').setAttribute('player-info', 'name', this.value)"
    />

    <a-scene
      networked-scene="
        room: nametag;
        debug: true;
        adapter: wseasyrtc;
    "
    >
      <a-assets>
        <template id="rig-template">
          <a-entity></a-entity>
        </template>

        <template id="head-template">
          <a-entity class="avatar" player-info>
            <a-sphere class="head" scale="0.2 0.22 0.2"></a-sphere>
            <a-entity class="face" position="0 0.05 0">
              <a-sphere class="eye" color="white" position="0.06 0.05 -0.16" scale="0.04 0.04 0.04">
                <a-sphere class="pupil" color="black" position="0 0 -1" scale="0.2 0.2 0.2"></a-sphere>
              </a-sphere>
              <a-sphere class="eye" color="white" position="-0.06 0.05 -0.16" scale="0.04 0.04 0.04">
                <a-sphere class="pupil" color="black" position="0 0 -1" scale="0.2 0.2 0.2"></a-sphere>
              </a-sphere>
            </a-entity>

            <!-- here we add a text component for a nametag; the value will be updated by the player-info component -->
            <a-text
              class="nametag"
              value="?"
              rotation="0 180 0"
              position=".25 -.35 0"
              side="double"
              scale=".5 .5 .5"
            ></a-text>
          </a-entity>
        </template>
      </a-assets>

      <a-entity environment="preset:starry;groundColor:#000000;"></a-entity>

      <a-entity id="rig" movement-controls="fly:true;" spawn-in-circle="radius:3" networked="template:#rig-template;">
        <a-entity
          id="player"
          camera
          position="0 1.6 0"
          look-controls
          networked="template:#head-template;"
          visible="false"
        ></a-entity>
      </a-entity>
    </a-scene>
  </body>
</html>
